home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mush-7.1.1 / lock.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-02  |  4.5 KB  |  225 lines

  1. /*
  2.  * lock.c -- deal with file locking on various architectures and UNIXs.
  3.  * dot_lock() creates a file with the same name as the parameter passed
  4.  * with the appendage ".lock" -- this is to be compatible with certain
  5.  * systems that don't use flock or lockf or whatever they have available
  6.  * that they don't use.
  7.  */
  8.  
  9. #ifdef USG
  10. #include <unistd.h>
  11. #endif /* USG */
  12. #include "mush.h"
  13. #if defined(SYSV) && !defined(USG)
  14. #include <sys/locking.h>
  15. #endif /* SYSV && !USG */
  16.  
  17. #ifdef DOT_LOCK
  18. extern int sgid;
  19. #ifdef BSD
  20. extern int rgid;
  21. #endif /* BSD */
  22.  
  23. dot_lock(filename)
  24. char *filename;
  25. {
  26.     char buf[MAXPATHLEN];
  27.     int lockfd, cnt = 0;
  28.     SIGRET (*oldint)(), (*oldquit)();
  29.  
  30. #ifdef SYSV
  31.     /* Only the spoolfile needs to be dot_locked -- other files are
  32.      * handled by lock_fopen, below.  To avoid collisions with 14-char
  33.      * file name limits, we allow dot_locking ONLY of the spoolfile.
  34.      */
  35.     if (strcmp(spoolfile, filename) != 0)
  36.     return 0;
  37. #endif
  38. #ifdef BSD
  39.     setregid(rgid, sgid);
  40. #else /* BSD */
  41.     setgid(sgid);
  42. #endif /* BSD */
  43. #ifdef M_XENIX
  44.     (void) sprintf(buf, "/tmp/%.10s.mlk", login);
  45. #else /* M_XENIX */
  46.     (void) sprintf(buf, "%s.lock", filename);
  47. #endif /* M_XENIX */
  48.     on_intr();
  49.     while ((lockfd = open(buf, O_CREAT|O_WRONLY|O_EXCL, 0444)) == -1) {
  50.     if (errno != EEXIST) {
  51.         error("unable to lock %s", filename);
  52.         break;
  53.     }
  54.     if (cnt++ == 0)
  55.         print("%s already locked, waiting", filename);
  56.     else
  57.         print_more(".");
  58.     sleep(1);
  59.     if (ison(glob_flags, WAS_INTR)) {
  60.         print_more("\nAborted.\n");
  61.         break;
  62.     }
  63.     }
  64.     off_intr();
  65.     if (lockfd != -1) {
  66.     if (cnt)
  67.         print("done.\n");
  68.     (void) close(lockfd);
  69.     }
  70. #ifdef BSD
  71.     setregid(sgid, rgid);
  72. #else
  73.     setgid(getgid());
  74. #endif /* BSD */
  75.     return lockfd == -1? -1 : 0;
  76. }
  77. #endif /* DOT_LOCK */
  78.  
  79. #ifdef SYSV
  80.  
  81. /*
  82.  * Define some BSD names for the SYSV world
  83.  */
  84. #ifdef USG
  85. #define LOCK_SH F_RDLCK
  86. #define LOCK_EX F_WRLCK
  87. #define LOCK_UN F_UNLCK
  88. #else /* USG */
  89. #define LOCK_SH LK_LOCK
  90. #define LOCK_EX LK_LOCK
  91. #define LOCK_UN LK_UNLCK
  92. #endif /* USG */
  93. #define LOCK_NB 0    /* Always non-blocking in this case */
  94.  
  95. #ifdef HPUX
  96. #undef EWOULDBLOCK
  97. #endif /* HPUX */
  98. #define EWOULDBLOCK    EAGAIN
  99.  
  100. flock(fd, op)
  101. int fd, op;
  102. {
  103. #ifndef USG
  104.     (void) locking(fd, op, 0); /* old xenix (sys III) */
  105.     return 0;
  106. #else
  107.     struct flock l;
  108.  
  109.     l.l_len = 0L;
  110.     l.l_start = 0L;
  111.     l.l_whence = 1;
  112.     l.l_type = op;
  113.  
  114.     return fcntl(fd, F_SETLK, &l);
  115. #endif /* USG */
  116. }
  117.  
  118. #endif /* SYSV */
  119.  
  120. FILE *
  121. lock_fopen(filename, mode)
  122. char *filename;
  123. char *mode;
  124. {
  125.     FILE *mail_fp = NULL_FILE;
  126. #ifndef LCKDFLDIR
  127.     int fd, lk;
  128.     int cnt = 0;
  129.     SIGRET (*oldint)(), (*oldquit)();
  130. #else /* LCKDFLDIR */
  131.     extern FILE *lk_fopen();
  132. #endif /* !LCKDFLDIR */
  133.  
  134.     if (debug && do_set(set_options, "deadlock")) {
  135.     (void) un_set(&set_options, "deadlock");
  136.     return NULL_FILE;
  137.     }
  138.  
  139. #ifdef LCKDFLDIR
  140.     return lk_fopen(filename, mode, NULL, NULL, 0);
  141. #else /* !LCKDFLDIR */
  142.  
  143. #ifdef DOT_LOCK
  144.     if (dot_lock(filename) == 0)
  145. #endif /* DOT_LOCK */
  146.     mail_fp = mask_fopen(filename, mode);
  147.     if (!mail_fp)
  148.     return NULL_FILE;
  149.     fd = fileno(mail_fp);
  150.  
  151.     if (mode[0] != 'r' || mode[1] == '+')
  152.     lk = LOCK_EX | LOCK_NB;
  153.     else
  154.     lk = LOCK_SH | LOCK_NB;
  155.  
  156.     on_intr();
  157.     while (isoff(glob_flags, WAS_INTR) && flock(fd, lk)) {
  158.     if (errno == EWOULDBLOCK) {
  159.         if (isoff(glob_flags, REDIRECT))
  160.         if (!cnt++)
  161.             print("\nwaiting to lock");
  162.         else
  163.             print(".");
  164.     } else {
  165.         error("Unable to lock \"%s\"", filename);
  166.         (void) fclose(mail_fp);
  167.         off_intr();
  168.         return NULL_FILE;
  169.     }
  170.     (void) fflush(stdout);
  171.     sleep(1);
  172.     }
  173.     if (cnt)
  174.     print("\n");
  175.     cnt = (ison(glob_flags, WAS_INTR) != 0);
  176.     off_intr();
  177.     if (cnt) {
  178.     (void) fclose(mail_fp);
  179.     return NULL_FILE;
  180.     }
  181.     return mail_fp;
  182. #endif /* LCKDFLDIR */
  183. }
  184.  
  185. /*ARGSUSED*/
  186. close_lock(filename, fp)
  187. char *filename;
  188. FILE *fp;
  189. #ifdef LCKDFLDIR
  190. {
  191.     return lk_fclose(fp, filename, NULL, NULL);
  192. }
  193. #else /* !LCKDFLDIR */
  194. {
  195. #ifdef DOT_LOCK
  196.     char buf[MAXPATHLEN];
  197. #endif /* DOT_LOCK */
  198.  
  199.     fflush(fp);
  200. #ifdef DOT_LOCK
  201. #ifdef BSD
  202.     setregid(rgid, sgid);
  203. #else
  204.     setgid(sgid);
  205. #endif /* BSD */
  206. #ifdef SYSV
  207.     if (strcmp(spoolfile, filename) == 0)
  208. #endif /* SYSV */
  209. #ifdef M_XENIX
  210.     (void) unlink(sprintf(buf, "/tmp/%.10s.mlk", login));
  211. #else /* M_XENIX */
  212.     (void) unlink(sprintf(buf, "%s.lock", filename));
  213. #endif /* M_XENIX */
  214. #ifdef BSD
  215.     setregid(sgid, rgid);
  216. #else
  217.     setgid(getgid());
  218. #endif /* BSD */
  219. #endif /* DOT_LOCK */
  220.  
  221.     (void) flock(fileno(fp), LOCK_UN);
  222.     return fclose(fp);
  223. }
  224. #endif /* LCKDFLDIR */
  225.